/*
 * ImageIOHelper.java
 *
 * Created on December 24, 2007, 1:15 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package net.sourceforge.jtocr;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import java.util.StringTokenizer;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;

import org.apache.log4j.Logger;

import com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;

/**
 *
 * @author Quan Nguyen (nguyenq@users.sf.net)
 */
public class ImageIOHelper {
    
    private static File imageFileName;
    private static Logger logger = Logger.getLogger(ImageIOHelper.class.getName());

	/**
     * Creates a new instance of ImageIOHelper
     */
    public ImageIOHelper() {
    }
    
    public static ArrayList<File> createImages(File imageFile, int index, boolean all, String imageFormat) {
        ArrayList<File> tempFileNames = new ArrayList<File>();
        
        try {
            
            Iterator readers = ImageIO.getImageReadersByFormatName(imageFormat);
            ImageReader reader = (ImageReader) readers.next();
            
            ImageInputStream iis = ImageIO.createImageInputStream(imageFile);
            reader.setInput(iis);
            //Read the stream metadata
            IIOMetadata streamMetadata = reader.getStreamMetadata();
            
            
            //Set up the writeParam
            TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.US);
            tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
            
            //Get tif writer and set output to file
            Iterator writers = ImageIO.getImageWritersByFormatName("tiff");
            ImageWriter writer = (ImageWriter)writers.next();
            
            if (all) {
                int imageTotal = reader.getNumImages(true);
                
                for (int i = 0; i < imageTotal; i++) {
//                BufferedImage bi = (BufferedImage) imageList.get(imageIndex).getImage();
                    BufferedImage bi = reader.read(i);
                    IIOImage image = new IIOImage(bi, null, reader.getImageMetadata(i));
                    File tempFile = tempImageFile(imageFile, i);
                    ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);
                    writer.setOutput(ios);
                    writer.write(streamMetadata, image, tiffWriteParam);
                    ios.close();
                    tempFileNames.add(tempFile);
                }
            } else {
                BufferedImage bi = reader.read(index);
                IIOImage image = new IIOImage(bi, null, reader.getImageMetadata(index));
                File tempFile = tempImageFile(imageFile, index);
                ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);
                writer.setOutput(ios);
                writer.write(streamMetadata, image, tiffWriteParam);
                ios.close();
                tempFileNames.add(tempFile);
            }
            writer.dispose();
            reader.dispose();
            iis.close();
        } catch (Exception exc) {
            exc.printStackTrace();
        }
        return tempFileNames;
        
    }
    
    public static File tempImageFile(File imageFile, int index) {
        String path = imageFile.getPath();
        StringBuffer strB = new StringBuffer(path);
        strB.insert(path.lastIndexOf('.'), index);
        return new File(strB.toString().replaceFirst("(?<=\\.)(\\w+)$", "tif"));
    }
        
    public static ArrayList<ImageIconScalable> getImageList(File imageFile) {
        ArrayList<ImageIconScalable> al = new ArrayList<ImageIconScalable>();
        try {
            String imageFileName = imageFile.getName();
            String imageFormat = imageFileName.substring(imageFileName.lastIndexOf('.') + 1);
            if(imageFormat.equals("pdf")){
            	
            	 RandomAccessFile raf = new RandomAccessFile(imageFile, "r");            	 
            	 FileChannel channel = raf.getChannel();
            	 ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY,
            	         0, channel.size());
            	 PDFFile pdffile = new PDFFile(buf);

            	 //   get number of pages
//            	 int jumlahhalaman = pdffile.getNumPages();

            	 //  iterate through the number of pages
//            	 for (int i = 1; i <= jumlahhalaman; i++) {
            	     PDFPage page = pdffile.getPage(1);

            	    // logger.debug("Analiza la primera p�gina del documento");
            	     //  create new image
            	     Rectangle rect = new Rectangle(0, 0,
            	             (int) page.getBBox().getWidth(),
            	             (int) page.getBBox().getHeight());

            	     Image img = page.getImage(
            	             rect.width+2300, rect.height+2000, //width & height
            	             rect, // clip rect
            	             null, // null for the ImageObserver
            	             true, // fill background with white
            	             true // block until drawing is done
            	             );

            	     BufferedImage bufferedImage = new BufferedImage(rect.width+2300, rect.height+2000, BufferedImage.TYPE_INT_RGB);
            	     Graphics g = bufferedImage.createGraphics();
            	     g.drawImage(img, 0, 0, null);
            	     g.dispose();

        			String fileName=imageFileName.substring(0, imageFileName.lastIndexOf('.'));
        			String fileNameSinEspacios="";
        			
        			StringTokenizer stTexto = new StringTokenizer(fileName);
        			
        			while (stTexto.hasMoreElements())
        				fileNameSinEspacios += stTexto.nextElement();
            			
            	     File imagepng = new File(fileNameSinEspacios+".png");
            	     imagepng.getAbsolutePath();
            	     if (imagepng.exists()) {
            	         imagepng.delete();
            	     }
            	     ImageIO.write(bufferedImage, "png", imagepng);
            	    // logger.debug("Guardar la imagen en formato png");

//            	 }

            	 imageFormat="png";
            	 imageFile=imagepng;
            	 //cerrar todo lo relacionado con el pdf
            	 raf.close();          	 
            }
            setImageFileName(imageFile);	 
            Iterator readers = ImageIO.getImageReadersByFormatName(imageFormat);
            ImageReader reader = (ImageReader) readers.next();
            
            if (reader == null) {
				logger.info("Need to install JAI Image I/O package.\nhttps://jai-imageio.dev.java.net");

                return null;
            }
            
            ImageInputStream iis = ImageIO.createImageInputStream(imageFile);

            reader.setInput(iis);
            
            int imageTotal = reader.getNumImages(true);
            
            for (int i = 0; i < imageTotal; i++) {
                al.add(new ImageIconScalable(reader.read(i)));
            }
            
            reader.dispose();
            iis.close();
        } catch (IOException ioe) {
            System.err.println(ioe.getMessage());
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
       
        return al;
    }

	public static File getImageFile() {
		return imageFileName;
	}

	public static void setImageFileName(File imageFile) {
		imageFileName = imageFile;
	}
}
